<template>
    <div>
        <ElCard class="marginBottom">
            <ElForm inline>
                <ElFormItem label="菜单名" style="margin-bottom: 0;">
                    <ElInput v-model="searchMenuName" placeholder="请输入菜单名" maxlength="30" show-word-limit></ElInput>
                </ElFormItem>
                <ElFormItem style="margin-bottom: 0;">
                    <ElButton @click="onSearchMenu" type="primary">搜索</ElButton>
                    <ElButton @click="onReset" type="primary">重置</ElButton>
                </ElFormItem>
            </ElForm>
        </ElCard>
        <ElCard>
            <template #header>
                <ElButton type="primary" @click="onAddMenu()" v-hasPermi="['sys:menu:insert']">新增菜单</ElButton>
            </template>
            <ElTable :data="sysMenuVOArray" row-key="id" v-loading="isLoading">
                <ElTableColumn label="菜单名" prop="name"></ElTableColumn>
                <ElTableColumn label="菜单类型">
                    <template #="{ row }: { row: SysMenuVO }">
                        <span v-if="row.type == SysMenuType.DIR">目录</span>
                        <span v-if="row.type == SysMenuType.ITEM">菜单</span>
                        <span v-if="row.type == SysMenuType.BUTTON">按钮</span>
                    </template>
                </ElTableColumn>
                <ElTableColumn label="路由路径" prop="path"></ElTableColumn>
                <ElTableColumn label="组件路径" prop="component"></ElTableColumn>
                <ElTableColumn label="图标">
                    <template #="{ row }: { row: SysMenuVO }">
                        <ElIcon v-if="row.icon">
                            <component :is="row.icon"></component>
                        </ElIcon>
                    </template>
                </ElTableColumn>
                <ElTableColumn label="权限标识" prop="perms"></ElTableColumn>
                <ElTableColumn label="排序" prop="sort"></ElTableColumn>
                <ElTableColumn label="操作" width="500px">
                    <template #="{ row, $index }: { row: SysMenuVO, $index: number }">
                        <ElButton v-if="row.type != SysMenuType.BUTTON" type="primary" @click="onAddMenu(row)"
                            v-hasPermi="['sys:menu:insert']">添加子菜单
                        </ElButton>
                        <ElButton type="warning" @click="onEditMenu(row)" v-hasPermi="['sys:menu:update']">编辑</ElButton>
                        <Popconfirm :title="`确定删除${row.name}?`" icon="Delete" @confirm="onDeleteMenu(row)">
                            <ElButton type="danger" v-hasPermi="['sys:menu:delete']">删除</ElButton>
                        </Popconfirm>
                    </template>
                </ElTableColumn>
            </ElTable>
        </ElCard>

        <!-- 菜单 新增/编辑 对话框 -->
        <ElDialog v-model="dialogInfo.show" :title="dialogInfo.title" width="700px" :show-close="false"
            :close-on-press-escape="false" :close-on-click-modal="false">
            <ElForm ref="formInstance" label-position="right" label-width="auto" :rules="dialogFormRules"
                :model="formInfo">
                <ElRow>
                    <ElCol :span="24">
                        <ElFormItem label="父级菜单" prop="parentId">
                            <ElTreeSelect node-key="id" value-key="id" highlight-current check-strictly
                                auto-expand-parent :default-expanded-keys="[formInfo.parentId]"
                                v-model="formInfo.parentId" :props="{ children: 'children', label: 'name' }"
                                :data="[{ id: rootMenuId, name: '根目录', children: sysMenuVOArray }]" />
                        </ElFormItem>
                    </ElCol>
                </ElRow>
                <ElRow>
                    <ElCol :span="12">
                        <ElFormItem label="菜单类型" prop="type">
                            <ElRadioGroup v-model="formInfo.type">
                                <ElRadio :value="SysMenuType.DIR">目录</ElRadio>
                                <ElRadio :value="SysMenuType.ITEM">菜单</ElRadio>
                                <ElRadio :value="SysMenuType.BUTTON">按钮</ElRadio>
                            </ElRadioGroup>
                        </ElFormItem>
                    </ElCol>
                    <ElCol :span="4" v-show="formInfo.type == SysMenuType.ITEM">
                        <ElFormItem label="设为首页">
                            <ElSwitch v-model="formInfo.isHome" />
                        </ElFormItem>
                    </ElCol>
                    <ElCol :span="6" v-show="formInfo.type != SysMenuType.BUTTON">
                        <ElFormItem label="图标" prop="icon">
                            <ElIconPicker v-model="formInfo.icon" />
                        </ElFormItem>
                    </ElCol>
                </ElRow>
                <ElRow>
                    <ElCol :span="12">
                        <ElFormItem label="排序" prop="sort">
                            <ElInputNumber :min="0" :max="200" v-model="formInfo.sort" style="width: 150px" />
                        </ElFormItem>
                    </ElCol>
                    <ElCol :span="12">
                        <ElFormItem label="菜单名称" prop="name">
                            <ElInput v-model="formInfo.name" placeholder="请输入菜单名称" maxlength="50" show-word-limit />
                        </ElFormItem>
                    </ElCol>
                </ElRow>
                <ElRow>
                    <ElCol :span="12" v-if="formInfo.type != SysMenuType.DIR">
                        <ElFormItem prop="perms" label-width="100">
                            <ElInput v-model="formInfo.perms" placeholder="请输入权限标识" maxlength="50" show-word-limit />
                            <template #label>
                                <span>
                                    <ElTooltip content="控制器中定义的权限字符，如：'system:user:list'" placement="bottom">
                                        <ElIcon style="vertical-align: middle">
                                            <QuestionFilled />
                                        </ElIcon>
                                    </ElTooltip>
                                    权限标识
                                </span>
                            </template>
                        </ElFormItem>
                    </ElCol>
                    <ElCol :span="12" v-if="formInfo.type != SysMenuType.BUTTON">
                        <ElFormItem label="路由路径" prop="path">
                            <ElInput v-model="formInfo.path" placeholder="请输入路由路径" maxlength="50" show-word-limit />
                        </ElFormItem>
                    </ElCol>
                </ElRow>
                <ElRow v-if="formInfo.type == SysMenuType.ITEM">
                    <ElCol :span="24">
                        <ElFormItem label="组件路径" prop="component">
                            <ElInput v-model="formInfo.component" placeholder="请输入组件路径" maxlength="50"
                                show-word-limit />
                        </ElFormItem>
                    </ElCol>
                </ElRow>
            </ElForm>
            <template #footer>
                <ElButton @click="hideDialog">取消</ElButton>
                <ElButton type="primary" @click="submitFormData()">确认</ElButton>
            </template>
        </ElDialog>
    </div>
</template>

<script setup lang="ts">
import { addMenu, deleteMenu, queryMenuAllTree, updateMenu } from '@/api/sysMenu/sysMenu';
import { SysMenuType, sysMenuVOToDTO, type SysMenuDTO, type SysMenuFiltDTO, type SysMenuVO } from '@/api/sysMenu/sysMenuType';
import ElIconPicker from '@/components/custom/ElIconPicker.vue';
import { useFormDialog } from '@/hook/useDialog';
import { QuestionFilled } from '@element-plus/icons-vue';
import { ElButton, ElCol, ElDialog, ElForm, ElFormItem, ElIcon, ElInput, ElInputNumber, ElRadio, ElRadioGroup, ElRow, ElSwitch, ElTooltip, ElTreeSelect, type FormRules } from 'element-plus';
import { onBeforeMount, reactive, ref } from 'vue';

const rootMenuId: string = "0"
/**
 * 搜索筛选菜单名
 */
const searchMenuName = ref<string>()
/**
 * 当前界面总的菜单信息
 */
const sysMenuVOArray = ref<SysMenuVO[]>()
/**
 * 数据是否正在加载中
 */
const isLoading = ref<boolean>(false)

/**
 * 初始化界面数据显示
 */
const initViewData = async (sysMenuFiltDTO?: SysMenuFiltDTO) => {
    isLoading.value = true
    sysMenuVOArray.value = await queryMenuAllTree(sysMenuFiltDTO)
    isLoading.value = false
}

/**
 * 挂载前执行
 */
onBeforeMount(() => {
    initViewData()
})

/**
 * 搜索
 */
const onSearchMenu = () => {
    initViewData({
        name: searchMenuName.value
    })
}

/**
 * 重置搜索筛选条件
 */
const onReset = () => {
    initViewData()
}

/**
 * 新增菜单
 * @param parentSysMenuVO 要添加到的父菜单
 */
const onAddMenu = (parentSysMenuVO?: SysMenuVO) => {
    showDialog('新增菜单', {
        parentId: parentSysMenuVO?.id ?? rootMenuId,
        type: SysMenuType.DIR
    } as SysMenuDTO, () => addMenu(formInfo.value))
}

/**
 * 修改菜单
 * @param sysMenuVO 要修改的菜单
 */
const onEditMenu = (sysMenuVO: SysMenuVO) => {
    showDialog('编辑菜单', sysMenuVOToDTO(sysMenuVO), () => updateMenu({ id: formInfo.value.id }, formInfo.value))
}

/**
 * 删除菜单
 * @param sysMenuVO 要删除的菜单
 */
const onDeleteMenu = async (sysMenuVO: SysMenuVO) => {
    await deleteMenu({ id: sysMenuVO.id })
    initViewData()
}

/**
 * 菜单 新增/编辑 对话框相关内容
 */
const {
    showDialog,
    hideDialog,
    submitFormData,
    dialogInfo,
    formInfo,
    formInstance
} = useFormDialog<SysMenuDTO>(() => initViewData())

/**
 * 对话框校验规则
 */
const dialogFormRules = reactive<FormRules>({
    parentId: {
        required: true, message: "请选择父级目录", trigger: "blur"
    },
    type: {
        required: true, message: "请选择菜单类型", trigger: 'blur'
    },
    sort: {
        required: true, message: "请输入排序序号", trigger: 'blur'
    },
    path: [
        { required: true, message: "请输入路由路径", trigger: 'blur' },
        { min: 2, max: 50, message: '路由路径长度为2 - 50', trigger: 'blur' }
    ],
    name: [
        { required: true, message: '请输入菜单名称', trigger: 'blur' },
        { min: 2, max: 30, message: '菜单名称长度为2 - 30', trigger: 'blur' }
    ],
    component: [
        { required: true, message: '请输入组件路径', trigger: 'blur' },
        { min: 2, max: 50, message: '组件路径长度为2 - 50', trigger: 'blur' }
    ]
})
</script>

<style scoped lang="scss"></style>